package com.lagou.registry;

import com.alibaba.fastjson.JSON;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * zk注册中心抽象类，实现核心方法
 */
public abstract class ZkRegistry implements ApplicationContextAware {

    private static final String REGISTRY_NAMESPACE = "/registry";
    protected String currentNamespace = REGISTRY_NAMESPACE + getPath();
    protected ApplicationContext ac;

    /**
     * 子类实现，该注册中心所处的路径
     * @return
     */
    public abstract String getPath();

    public abstract <T> Class<T> getServerNodeClass();

    /**
     * 启动式，初始化操作，1.providerRegistry负责通过注解扫描到对应的类，注册到zk注册中心
     */
    public abstract void init();
    /**
     * 注册服务器节点信息到zk，路径为命名空间+appName
     * @param node
     */
    public void registerServerNode(ServerNode node){
        ZkNodeUtil.createNodeAndData(CreateMode.EPHEMERAL_SEQUENTIAL,currentNamespace + "/" +node.getAppName(),JSON.toJSONString(node));
    }

    /**
     * 通过app名称获取服务器节点信息，根据子类的不同获取到不同类型的服务器节点信息
     * @param appName
     * @return
     */
    public ServerNode getServerNodeByApp(String appName){
        String jsonNode = ZkNodeUtil.getNodeData(currentNamespace + "/" + appName);
        ServerNode serverNode = JSON.parseObject(jsonNode,getServerNodeClass());
        return serverNode;
    }

    /**
     *
     * @param
     * @return
     */
    public boolean isExistsServerNode(String appName){
        return ZkNodeUtil.isExistsNode(currentNamespace + "/" + appName);
    }


    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ac = applicationContext;
    }

    public String getCurrentNamespace() {
        return currentNamespace;
    }
}
